package darknet.core.impl.net;

import java.net.InetAddress;

import darknet.core.spec.net.Node;
import darknet.core.spec.net.NodeState;

/**
 * Node implementation
 * 
 * @author yoyo
 */
@SuppressWarnings("serial")
public class NodeImpl implements Node {
    
    /** Name */
    private String name;
    
    /** Address */
    private InetAddress address;
    
    /** Port */
    private int port;

    /** State of the node. */
    private NodeState state;

    /**
     * Initialise a new Node.
     * 
     * @param name
     * @param address
     * @param port
     * @param state
     */
    public NodeImpl(String name, InetAddress address, int port,
            NodeState state) {
	
	if (name == null || name.length() == 0) {
	    throw new IllegalArgumentException("port is invalid");
	}
	this.port = port;
	
	if (address == null) {
	    throw new IllegalArgumentException("address is null");
	}
	this.address = address;
	
	if (port <= 0) {
	    throw new IllegalArgumentException("port is invalid");
	}
	this.port = port;

        if (state == null) {
            throw new IllegalArgumentException("state is null");
        }
        this.state = state;

	this.name = name;
	this.address = address;
	this.port = port;
    }

    @Override
    public InetAddress getAddress() {
	return address;
    }

    @Override
    public String getName() {
	return name;
    }

    @Override
    public int getPort() {
	return port;
    }

    @Override
    public NodeState getState() {
        return state;
    }
    
    /**
     * Set the node address.
     * 
     * @param address
     */
    public void setAddress(InetAddress address) {
	
	if (address == null) {
	    throw new IllegalArgumentException("address is null");
	}
	this.address = address;
    }
    
    /**
     * Set the node port.
     * 
     * @param port
     */
    public void setPort(int port) {
	
	if (port <= 0) {
	    throw new IllegalArgumentException("port is invalid");
	}
	this.port = port;
    }

    /**
     * Set the state.
     * 
     * @param newState
     */
    public void setState(NodeState newState) {

        if (newState == null) {
            throw new IllegalArgumentException("newState is null");
        }
        this.state = newState;
    }

    @Override
    public boolean equals(Object obj) {
	return obj instanceof NodeImpl && 
		((NodeImpl)obj).getName().equals(getName());
    }

    @Override
    public int hashCode() {
	return getName().hashCode();
    }

    @Override
    public String toString() {
	StringBuilder builder = new StringBuilder();
	builder.append("NodeImpl [");
	builder.append("name=");
	builder.append(name);
	builder.append(", ");
	builder.append("address=");
	builder.append(address);
	builder.append(", ");
	builder.append("port=");
	builder.append(port);
        builder.append(", ");
        builder.append("state=");
	builder.append(state);
	builder.append("]");
	return builder.toString();
    }
}
